﻿using System;
using System.Collections.Generic;
using System.Linq;
using PostSharp.Aspects;
using System.ServiceModel;


namespace SecurityAgent
{
    [Serializable]
    public class UnauthorizedAccessException : Exception
    {
        public UnauthorizedAccessException()
        {
        }

        public UnauthorizedAccessException(string message)
            : base(message)
        { }

        public UnauthorizedAccessException(string message, Exception innerException)
            : base(message, innerException)
        {
        }

        public UnauthorizedAccessException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
            : base(info, context)
        {
        }

        public UnauthorizedAccessFault Fault { get; set; }

        public UnauthorizedAccessException(UnauthorizedAccessFault fault) : base(fault.Message)
        {
            Fault = fault;
        }
    }

    [Serializable]
    public class GeneralSecurityException : Exception
    {
        public GeneralSecurityException()
        {
        }

        public GeneralSecurityException(string message)
            : base(message)
        { }

        public GeneralSecurityException(string message, Exception innerException)
            : base(message, innerException)
        {
        }

        public GeneralSecurityException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
            : base(info, context)
        {
        }

        public SecurityFault Fault { get; set; }

        public GeneralSecurityException(SecurityFault fault) : base(fault.Message)
        {
            Fault = fault;
        }
    }

    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)]
    [Serializable]
    public class SASExceptionHandler : OnExceptionAspect
    {
        public override void OnException(MethodExecutionArgs args)
        {
            string message = string.Empty;
            //string message = "Application Key: " + 
            if (args.Exception is FaultException<UnauthorizedAccessFault>)
            {
                UnauthorizedAccessFault fault = ((FaultException<UnauthorizedAccessFault>)args.Exception).Detail;
                message = "Unauthorized Access Attempted"
                    + "\n " + fault.Message
                    + "\n Application Key: " + (String.IsNullOrEmpty(fault.Application) ? String.Empty : fault.Application)
                    + "\n User Token: " + (String.IsNullOrEmpty(fault.UserToken) ? String.Empty : fault.UserToken)
                    + "\n User Name: " + (String.IsNullOrEmpty(fault.UserName) ? String.Empty : fault.UserName)
                    + "\n Object: " + (String.IsNullOrEmpty(fault.Object) ? String.Empty : fault.Object)
                    + "\n Field: " + (String.IsNullOrEmpty(fault.Field) ? String.Empty : fault.Field)
                    + "\n Operation: " + (String.IsNullOrEmpty(fault.Operation) ? String.Empty : fault.Operation);


//                Logger.Write(new LogEntry { Message = message });
                throw new UnauthorizedAccessException(fault);
            }
            else if (args.Exception is FaultException<SecurityFault>)
            {
                SecurityFault fault = ((FaultException<SecurityFault>)args.Exception).Detail;
                message = "Secruity Agent Service Fault"
                    + "\n " + fault.Message
                    + "\n Application Key: " + (String.IsNullOrEmpty(fault.Application) ? String.Empty : fault.Application)
                    + "\n Argument 1: " + (String.IsNullOrEmpty(fault.Argument1) ? String.Empty : fault.Argument1)
                    + "\n Argument 2: " + (String.IsNullOrEmpty(fault.Argument2) ? String.Empty : fault.Argument2);

 //               Logger.Write(new LogEntry { Message = message, EventId = 3000, Severity = System.Diagnostics.TraceEventType.Critical });
                throw new GeneralSecurityException(fault);
            }
            else
            {
                args.FlowBehavior = FlowBehavior.RethrowException;
            }
            //base.OnException(args);

        }
    }

}
